package controllers

import (
	"backend/common"
	"backend/models"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"

	"github.com/cloudwego/eino/schema"
	"github.com/gin-gonic/gin"
)

// GenerateWorkflow 生成工作流
func GenerateWorkflow(ctx *gin.Context) {
	// 解析请求
	mes := struct {
		IntentionID uint `json:"intentionID" binding:"required"`
	}{}
	err := ctx.ShouldBindJSON(&mes)
	if err != nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "请确认请求格式"})
		return
	}

	intention, err := getUserIntention(mes.IntentionID)
	if err != nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": err.Error()})
		fmt.Println(err)
		return
	}

	userID, _ := getUserID(ctx)
	if intention.UserID != userID {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "没有权限"})
		return
	}

	messages := []*schema.Message{
		schema.SystemMessage("你是一位项目工作流生成专家，擅长创建结构化、可扩展的项目工作流。请严格遵循以下规则和要求：\n\n" +
			"1. 工作流设计规则：\n" +
			"   - 将项目分解为清晰的步骤，每个节点对应实现中的一个函数/类\n" +
			"   - 节点描述要简洁(1-2句话)，明确说明其功能\n" +
			"   - 每个节点有唯一id，从1开始递增\n" +
			"   - 跳转条件使用伪代码格式(如: if x > threshold)\n" +
			"   - 只在必要时添加条件跳转，保持流程简洁\n" +
			"   - 工作流要与目标编程语言特性深度结合\n" +
			"   - 至少要输出一个结点\n\n" +

			"2. 输出质量要求：\n" +
			"   - 节点描述要具体，避免模糊\n" +
			"   - 保持流程线性，只在逻辑必要时添加分支\n" +
			"   - 确保每个节点的输入输出与上下文匹配\n" +
			"   - 跳转条件要合理且必要"),

		schema.SystemMessage("输入格式:\n" +
			`{
  "intention": "<项目目标>",
  "func": [
    {
      "name": "<功能名>",
      "description": "<功能描述>",
      "input": "<输入>",
      "output": "<输出>"
    }
  ],
  "language": "<编程语言>"
}`),

		schema.SystemMessage("你必须严格按照以下JSON格式输出，不要包含任何额外解释或注释：\n\n" +
			`{
  "workflow": {
    "workflow": "<简要概述>",
    "dataflows": [
      {
        "id": <数字>,
        "name": "<简短名称>",
        "description": "<1-2句功能描述>",
        "input": "<输入列表>",
        "output": "<输出列表>",
        "jump-list": [
          {
            "condition": "if <伪代码条件>", 
            "id": <目标节点>
          }
        ]
      }
    ],
    "language": "<编程语言>"
  },
  "ok": <如果无法生成工作流，此项为false，并且其他项为空,否则为true>
}`),

		schema.UserMessage(intention.Request),
	}

	//生成回复
	response, err := common.Interact(messages)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"status":  "error",
			"message": "服务器错误101",
		})
		return
	}
	// fmt.Println(response.Content)
	//解析回复
	res := models.WorkflowMessage{}
	// err = json.Unmarshal([]byte(response.Content)[7:len(response.Content)-3], &res)
	err = json.Unmarshal([]byte(response.Content), &res)

	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"status":  "error",
			"message": "服务器错误102 " + err.Error(),
		})
		return
	}

	if res.Ok == false {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{
			"status":  "error",
			"message": "无效输入",
		})
	} else {
		//TODO
		workflow, err := createDataflow(userID, mes.IntentionID, res.Workflow)
		if err != nil {
			ctx.JSON(http.StatusInternalServerError, gin.H{
				"status":  "error",
				"message": "无法保存工作流",
			})
			return
		}

		ctx.JSON(http.StatusOK, gin.H{
			"status":  "success",
			"message": "成功生成工作流",
			"data": struct {
				Workflow   models.Workflow `json:"workflow"`
				WorkflowID uint            `json:"workflowID"`
			}{res.Workflow, workflow.ID},
		})
	}
}

// ChangeWorkflow 工作流更改
func ChangeWorkflow(ctx *gin.Context) {
	// 解析请求
	mes := struct {
		Workflow   models.Workflow `json:"workflow" binding:"required"`
		WorkflowID uint            `json:"workflowID" binding:"required"`
	}{}
	err := ctx.ShouldBindJSON(&mes)
	if err != nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "请确认请求格式"})
	}

	workflowJS, err := json.MarshalIndent(mes.Workflow, "", "  ")
	if err != nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "请确认请求格式2 " + err.Error()})
		return
	}

	// TODO 更改工作流到数据库
	userID, _ := getUserID(ctx)
	dataflow := &models.Dataflow{
		ID:       mes.WorkflowID,
		UserID:   userID,
		Dataflow: string(workflowJS),
	}
	err = updateDataflow(dataflow, userID)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "更新失败" + err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "成功更改工作流",
	})
}

func GetWorkflow(ctx *gin.Context) {
	// 解析请求
	workflowIDS := ctx.Query("workflowID")
	workflowID, err := strconv.ParseUint(workflowIDS, 10, 64)

	if err != nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "请确认请求格式" + err.Error()})
		return
	}

	workflow, _ := getDataflow(uint(workflowID))
	if workflow == nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "查询失败"})
		return
	}

	userID, _ := getUserID(ctx)
	if workflow.UserID != userID {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "没有权限"})
		return
	}

	workflowV := models.Workflow{}
	err = json.Unmarshal([]byte(workflow.Dataflow), &workflowV)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "服务器错误"})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "成功获取",
		"data": struct {
			Workflow models.Workflow `json:"workflow"`
		}{workflowV},
	})
}

func GetWorkflowByIntention(ctx *gin.Context) {
	// 解析请求
	intentionIDS := ctx.Query("intentionID")
	intentionID, err := strconv.ParseUint(intentionIDS, 10, 64)

	if err != nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "请确认请求格式" + err.Error()})
		return
	}

	workflow, _ := getDataflowByIntention(uint(intentionID))
	if workflow == nil {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "查询失败"})
		return
	}

	userID, _ := getUserID(ctx)
	if workflow.UserID != userID {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"status": "error", "message": "没有权限"})
		return
	}

	workflowV := models.Workflow{}
	err = json.Unmarshal([]byte(workflow.Dataflow), &workflowV)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "服务器错误"})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"status":  "success",
		"message": "成功获取",
		"data": struct {
			Workflow models.Workflow `json:"workflow"`
		}{workflowV},
	})
}
